﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Net;
using System.Diagnostics;

using Seven.Member.Web.Model;

namespace Seven.Member.Web.Filters.Mvc
{
    /// <summary>
    /// 用于验证 ASP.NET MVC Controller/Action 访问请求登录状态的过滤器。
    /// 对于标记了 <see cref="AllowAnonymousAttribute"/> 或 <see cref="Seven.Web.Mvc.AuthorizeAttribute"/> 特性的 Controller/Action，将不会被该过滤器验证。
    /// </summary>
    public class LoginStatusAuthorizeAttribute : Seven.Web.Mvc.AuthorizeAttribute
    {
        /// <summary>
        /// 检查当前请求是否来自于有效的登录用户。
        /// </summary>
        /// <param name="filterContext"></param>
        /// <returns></returns>
        protected override bool AuthorizeCore(AuthorizationContext filterContext)
        {
            LoginModel model = LoginModelUtility.GetLoginModel(filterContext.HttpContext);
            bool isValid = LoginModelUtility.Validate(model);
            if (SEVENMemberWebConfig.DeveloperModel)
            {
                Debug.WriteLine("Mvc.LoginStatusAuthorizeAttribute.isValid:{0}", isValid);
                return true;
            }
            return isValid;
        }

        /// <summary>
        /// 当页面请求被判断为 未登录 时，所执行的动作（跳转到登录页面）。
        /// 如果当前请求是 AJAX 请求，则返回一个包含请求错误数据的 JSON 响应。
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
        {
            string originalUrl = filterContext.HttpContext.Request.Path;
            int statusCode = (int)HttpStatusCode.Unauthorized;
            string statusDescription = "登录超时或未登录，请重新登录！";
            bool friendlyHttpError = SEVENMemberWebConfig.FriendlyHttpError;

            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                if (friendlyHttpError)
                {
                    filterContext.Result = new JsonResult()
                    {
                        JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                        Data = new
                        {
                            statusCode = statusCode,
                            statusDescription = statusDescription,
                            returnUrl = originalUrl,
                            result = "Unauthorized"
                        }
                    };
                }
                else
                { filterContext.Result = new HttpStatusCodeResult(statusCode, statusDescription); }
            }
            else
            {
                string loginUrl = SEVENMemberWebConfig.LoginUrl,
                       suffix = (loginUrl.Contains("?") ? "&&" : "?") + "returnUrl=" + originalUrl;
                filterContext.Result = new RedirectResult(loginUrl + suffix);
            }
        }
    }
}
